home *** CD-ROM | disk | FTP | other *** search
- Page ,132
- title RDISK.ASM - Virtuelles Laufwerk
- ;**********************************************************;
- ; RDISK.ASM RAM-Disk fr Expanded Memory / Hauptspeicher. ;
- ; Version: 1.1 ;
- ; Sprache: Microsoft MASM 4.0 oder hher ;
- ; Autor: M. Greve ;
- ;bersetzen: MASM /ML RDISK; ;
- ; LINK RDISK; ;
- ; EXE2BIN RDISK.EXE RDISK.SYS ;
- ; Anwendung: DEVICE=RDISK.SYS [xxx] [/A] ;
- ;**********************************************************;
-
- ;-----( Befehle des EMM-Interrupts 67h )--------------------
- EMM = 67h ;Interrupt
- EMMframe = 41h ;Segment-Adr. des EMM
- EMMfree = 42h ;Freie Seiten ermitteln
- EMMalloc = 43h ;EMM-Seiten zuteilen
- EMMmapp = 44h ;Seite ins Fenster laden
- EMMsave = 47h ;EMM-Zustand sichern
- EMMreset = 48h ;EMM-Zugriff zulassen
-
- ;-----( Status-Codes )--------------------------------------
- CMD_ERR = 8103h ;Ungltiger Befehl
- CRC_ERR = 8104h ;CRC-Fehler
- SEC_ERR = 8108h ;Ungltiger Sektor
- GEN_ERR = 810Ch ;Undefinierter Fehler
- SZ_ERR = 00000001b ;Ungengend Speicher
- NoEMM_ERR = 00000100b ;Kein Expanded Speicher
- EMM_ERR = 00001000b ;Exp. Speicher Fehler
- OPT_ERR = 00010000b ;Ungltige Option
-
- ;-----( Allg. Konstanten )----------------------------------
- MEDIA_ID = 0F8h ;Media Descriptor Byte
- MAXFAT = 0FF7h ;Max. Anzahl FAT-Eintrge
- EXPANDED = 1 ;Expanded Speicher-Flag
- MIN_MEM = 64 ;Min. freier Speicher
- MIN_REQ = 16 ;kleinstmgliche RamDisk
- SECSZ = 512 ;Byte / Sektor
- DFLTSZ = 128 ;Default Diskgráe (64kB)
- MAXCMD = 12 ;Max. zugelassener Befehl
- READCMD = 4 ;Nummer des Lesebefehls
- CR = 0Dh
- LF = 0Ah
- BEEP = 7
-
- ;-----( Request-Header-Strukturen )-------------------------
- RH equ ES:[DI] ;Zugriffszeiger fr Request-Header
- RHx STRUC ;Gemeinsame Felder im Reqest-Header
- db ? ;Lnge d. Req.-Header
- db ? ;Gerte-(Einheit)-Nummer
- CMDcode db ? ;Befehls-Code
- CMDstat dw ? ;Statuswort
- dq ? ;Reserviert fr DOS
- RHx ENDS
- RH0 STRUC ;Fn.0:Init; Fn.1:Media Check; Fn.2: Build-BPB
- db (TYPE RHx) DUP (?) ; gemeinsamer Teil
- Unum db ? ;Anzahl inst. Gerte
- EndOfs dw ? ;Ende des Treibers, Offs
- EndSeg dw ? ;Ende des Treibers, Segm
- BPBofs dw ? ;BPB Tabelle, Offset
- BPBseg dw ? ;BPB Tabelle, Segment
- DrvCode db ? ;Laufw.-Code ab DOS 3.xx
- RH0 ENDS
- MediaCh equ byte ptr EndOfs ;"Media Change" Flag
- BPBadr equ dword ptr BPBofs;32Bit Adresse des BPB
-
- ;Beim Aufruf von "Init" zeigt BPBofs auf "DEVICE=" Zeile.
- ConfigLn equ dword ptr BPBofs
- RH4 STRUC ;Fn.4:Read; Fn.8:Write; Fn.9:Write/Verify
- db (TYPE RHx) DUP (?) ;gemeinsamer Teil
- db ? ;Media Descriptor Byte
- DTAadr dd ? ;DTA adresse (32Bit)
- SecCnt dw ? ;Sektorenzhler
- StrtSec dw ? ;Erster Sektor
- RH4 ENDS
-
- ;-----( Text-Ausgabe-Makro )--------------------------------
- @Print MACRO Text
- push DX
- lea DX,Text
- mov AH,9
- int 21h
- pop DX
- ENDM
-
- ;-----( Programmbeginn )------------------------------------
- CODE SEGMENT para public
- ASSUME CS:CODE, DS:CODE
- ORG 0
- Main:
- ;-----( Gertetreiberkopf )---------------------------------
- DvcHdr dd -1 ;Zeiger auf nchsten Treiber
- dw 0800h ;Block-Treiber-Attribut
- dw Strategy ;Strategy Routine
- dw DVCintrpt ;Interrupt-Routine
- db 'RAMD 1.0' ;Treibername (8Byte)
- ReqHdr dd ? ;Request-Header-Adresse
-
- ;-----( Funktionstabelle )----------------------------------
- ; Alle Funktionen werden ber die Adresse ES:Dispatch[BX]
- ; aufgerufen und kehren mit dem Fehlercode im AX-Register
- ; zu DOS zurck.
- ;-----------------------------------------------------------
- Dispatch dw Init ; 0 - Initialisierung
- dw MedChk ; 1 - Diskettenwechsel
- dw BldBPB ; 2 - BPB aufbauen
- dw Exit ; 3 - I/O Ctrl Ein
- dw Read ; 4 - Block lesen
- dw Exit ; 5 - Zeichen lesen
- dw Exit ; 6 - Eing. Status
- dw Exit ; 7 - Eingabe lschen
- dw Write ; 8 - Block schreiben
- dw Write ; 9 - Schreiben mit Verify
- dw Exit ;10 - Ausgabe Status
- dw Exit ;11 - Ausgabe lschen
- dw Exit ;12 - I/O Control Aus
-
- ;-----( Datenbereich )--------------------------------------
- Progname db CR,LF,'RDISK.SYS - (c) 1990 '
- db 'c''t / M. H. Grev',CR,LF,'$'
- EVEN ;gerade Adresse fr Stack!
- db 32 dup ('stak') ;programminterner Stack
- Stak: ;Stack-Kopf
- oldSP dw ? ;alter Stack-Pointer
- oldSS dw ?
- oldAX dw ? ;Ablage fr AX-Register
- Cmd db ? ;aktueller Befehl
- MemTyp db 0 ;0 = Hauptspeicher
- ;1 = Expanded Speicher
- Npages dw DFLTSZ/16 ;Diskgráe in EMM-Seiten
- FrameSeg dw ? ;Segment des EMM-Fensters
- XfrSec dw ? ;Sektor
- XfrCnt dw ? ;Sektorenzhler
- XfrAdr label dword ;lokale Kopie der
- XfrAdrO dw ? ;DTA-Adresse
- XfrAdrS dw ?
- EMMhdl dw ? ;EMM-Handle
- LastPge dw -1 ;Zuletzt verw. EMM-Seite
-
- ;-----( BIOS-Parameter-Block )------------------------------
- BPB equ $
- SecSz dw SECSZ ;Byte/Sektor
- ClstrSz db 2 ;Sektoren/Cluster
- ResSecs dw 1 ;Reserv. Sektoren
- db 1 ;Anzahl FAT-Kopien
- NDir dw DFLTSZ/4 ;Eintr. im Root
- DiskSz dw DFLTSZ ;Anzahl Sektoren
- db MEDIA_ID ;Media descriptor
- FATsec dw 2 ;Sektoren pro FAT
- dw 8 ;Sektoren pro Spur
- dw 1 ;Lesekpfe
- dw 0 ;Versteckte Sektoren
- BPBlen equ $ - BPB ;Lnge des BPB
- BPBptr dw offset BPB ;Zeiger auf BPB
-
- ;-----( Strategy )------------------------------------------
- ; Sichert Zeiger auf Request-Header
- ;-----------------------------------------------------------
- Strategy proc far
- mov word ptr CS:ReqHdr,BX
- mov word ptr CS:ReqHdr+2,ES
- ret
- Strategy endp
-
- ;-----( Gertetreiber-"Interrupt" )-------------------------
- DVCintrpt proc far
- mov CS:oldAX,AX ;Wert von AX sichern
- mov CS:oldSP,SP ;Alten Stack-Pointer sichern
- mov CS:oldSS,SS
- mov AX,CS
- cli
- mov SS,AX ;Eigenen Stack einrichten
- mov SP,offset Stak
- sti
- push BX
- push CX
- push DX
- push DS
- push ES
- push DI
- push SI
- push BP
- mov DS,AX ;DS-> Unsere Daten
- les DI,ReqHdr ;ES:DI -> Request-Header
- mov BL,RH.CMDcode ;BX = Befehls-Code
- sub BH,BH
- cmp BL,MAXCMD ;Befehl gltig ?
- mov AX,CMD_ERR ;Fehler-Code
- ja DVCend ;Abbruch!
- or BX,BX ;Initialisierung ?
- jz DVC1 ;Ja
- test MemTyp,EXPANDED ;EMM-Speicher ?
- jz DVC1 ;Nein
- mov AH,EMMsave ;EMM-Speicherzustand sichern
- mov DX,EMMhdl
- int EMM
- or AH,AH
- jnz DVCerr
- DVC1: add BX,BX ;BX = Befehlsindex
- call Dispatch[BX] ;Aufruf des Befehls
- les DI,ReqHdr ;ES:DI->Req. Header
- test MemTyp,EXPANDED
- jz DVCend
- cmp RH.CMDcode,0 ;Init. Befehl?
- je DVCend ;Ja
- push AX ;Statuswort sichern
- mov AH,EMMreset ;EMM-Zugriff zulassen
- mov DX,EMMhdl
- int EMM
- or AH,AH ;EMM-Fehler ?
- pop AX
- jz DVCend ;Alles OK
- DVCerr: mov AX,GEN_ERR ;Fehler melden
- DVCend: mov RH.CMDstat,AX ;Status in Req. Hdr ablegen
- pop BP ;Register zurcksetzen
- pop SI
- pop DI
- pop ES
- pop DS
- pop DX
- pop CX
- pop BX
- cli
- mov SS,CS:oldSS
- mov SP,CS:oldSP ;den Stack nicht vergessen !
- sti
- mov AX,CS:oldAX
- ret
- DVCintrpt endp
-
- ;-----( Funktion 1: Media Check )---------------------------
- ; Ueberprft ob Diskette gewechselt wurde.
- ;-----------------------------------------------------------
- MedChk: mov RH.MediaCh,1 ; nicht gewechselt
- sub AX,AX ; (es ist ja eine RAM-Disk!)
- ret
-
- ;-----( Funktion 2: Build BPB )-----------------------------
- ; Adresse der BPB-Tabelle an DOS zurckgeben.
- ;-----------------------------------------------------------
- BldBPB: mov RH.BPBofs,offset BPB
- mov RH.BPBseg,CS
- sub AX,AX
- ret
-
- ;-----( Funktionen 4, 8 und 9: Disk-Ein/Ausgabe )-----------
- Read:
- Write: cld ;Richtungsflag lschen
- mov LastPge,-1 ;Letzte EMM-Seite
- mov AL,RH.CMDcode
- mov Cmd,AL ;Befehl sichern
- mov AX,RH.StrtSec ;Erster Sektor > Diskgráe?
- cmp AX,DiskSz
- ja RWerr1 ;Ja, Sektorfehler
- mov XfrSec,AX ;Ersten Sektor sichern
- mov BX,RH.SecCnt ;Anzahl Sektoren sichern
- add AX,BX ;letzter Sektor > Diskgráe?
- cmp AX,DiskSz
- ja RWerr1 ;Ja, Sektorfehler
- mov XfrCnt,BX ;Anzahl Sektoren sichern
- les DI,RH.DTAadr ;Zeiger fr DTA-Adresse
- mov XfrAdrO,DI ;sichern
- mov XfrAdrS,ES
- RW0: cmp XfrCnt,0 ;alle Sektoren kopiert ?
- jz RWEnd ;Ja, Ende
- mov AX,XfrSec
- call MapSec ;ES:DI ->Sektor
- or AH,AH
- jnz RWerr2
- lds SI,XfrAdr ;DS:SI ->DOS Buffer(DTA)
- cmp CS:Cmd,READCMD
- jnz RW1
- xchg SI,DI ;Fr Lese-Befehl,
- push ES ;Adressen vertauschen
- push DS
- pop ES
- pop DS
- RW1: mov CX,SECSZ/2 ;Anzahl Worte
- rep movsw
- mov AX,CS ;DS ->unsere Daten
- mov DS,AX
- dec XfrCnt ;Zhler - 1
- inc XfrSec
- add XfrAdrO,SECSZ
- jmp RW0 ;nchsten Sektor
- RWerr1: mov AX,SEC_ERR ;Expanded-Memory-Fehler
- jmp RWEnd
- RWerr2: mov AX,CRC_ERR ;Ungltiger Sektor
- RWEnd: ret
-
- ;-----( Ungenutzte Funktionen )-----------------------------
- Exit: mov AX,CMD_ERR
- ret
-
- ;-----( Sektornummer in Speicheradresse umwandeln )---------
- ; Eingabe: AX = Sektornummer
- ; Ausgabe: ES:DI = -> Sektor
- ; AH <> 0: Fehler
- ;-----------------------------------------------------------
- MapSec: test MemTyp,EXPANDED
- jz MapSec2
- push AX ;EMM-Speicher
- mov CX,5 ;2^5=32 Sektoren/EMM-Seite
- shr AX,CL ;AX =EMM-Seite
- cmp AX,LastPge ;bereits eingeblendet ?
- je MapSec1 ;Ja
- mov LastPge,AX ;Nein, Seitennummer sichern
- mov BX,AX ;logische Seite 'BX' in
- sub AL,AL ;physikalische Seite 0
- mov AH,EMMmapp ;einblenden
- mov DX,EMMhdl
- int EMM
- or AH,AH
- jnz MapSecE
- MapSec1:pop DI ;DI = Sektornummer
- and DI,01Fh ;Maske f. unterste 5 Bit
- mov CX,9
- shl DI,CL ;ES:DI -> Segment Adresse
- mov ES,FrameSeg
- jmp MapSecE
- MapSec2:mov CX,5 ;2^5=32 Paragraphen
- shl AX,CL ;pro 512 Byte Sektor
- add AX,FrameSeg ;Segment-Adresse
- mov ES,AX ;CX = Segment
- sub DI,DI ;BX = 0 = Offset
- sub AX,AX
- MapSecE:ret
-
- ;-----( Ende des Treibers )---------------------------------
- ; Wenn die RAM-Disk im Hauptspeicher installiert wird, ist
- ; dies gleichzeitig der Anfang des Boot-Sektors (Sektor 0
- ; der RAM-Disk). Der nachfolgende Code befindet sich inner-
- ; halb dieses Sektors. Der Assemblerzeiger wird dazu auf
- ; eine runde Paragraphenadresse gesetzt. Beim Einsatz von
- ; Expanded Memory, ist dies das Ende des Treibers.
- ;-----------------------------------------------------------
- DVCLEN = ($-Main+15)/16 ;Treiberlnge in Paragraphen
- ORG DVCLEN*16
- BootRec db 0,0,0 ;Sektor 0 der Disk
- db 'RDISK1.0' ;8 Byte Bezeichnung
- BootBPB db BPBlen dup (?) ;Reservierter fr den BPB
- BOOTlen equ $ - offset BootRec
-
- ;----- (Funktion 0: Treiber installieren )------------------
- ErrFlag db 0 ;Flag fr Fehlermeldungen
-
- Init: call Parse ;Kommandozeile auswerten
- call Parms ;BPB Parameter berechnen
- call SetUp ;Speicher reservieren
- call Format ;Disk formatieren
- call SignOn ;Meldungen ausgeben
- call FillRH ;Parameter Rckgabe an DOS
- test ErrFlag,-1 ;Installationsfehler?
- jnz InitEnd
- ;FAT/Root Sektoren aus temp.
- mov AX,ResSecs ;Bereich an ihren end-
- call MapSec ;gltigen Platz verschieben.
- mov AX,32
- mul NDir ;Anz. Bytes im Root-Verz.
- mov CX,AX
- mov AX,512
- mul FATsec ;Anz. Bytes im FAT-Bereich
- add CX,AX
- push DS ;DS hinberretten
- mov DX,CS ;Prog.Segment + Prog.lnge
- add DX,DRIVERend ; = Adresse des
- mov DS,DX ;temporren Speichers
- sub SI,SI ;DS:SI -> temp. FAT/Root
- rep movsb ;Daten kopieren
- pop DS
- InitEnd:ret
-
- ;-----( "DEVICE="-Zeile auswerten )------------------------
- ; Eingabe: ES:DI = -> Request-Header
- ; Ausgabe: DX = Diskgráe in KByte
- ;-----------------------------------------------------------
- Parse: les DI,RH.ConfigLn ;ES:DI -> Text
- sub DX,DX
- ParsNxt:mov AL,ES:[DI]
- sub AH,AH
- inc DI ;DI -> nchstes Zeichen
- cmp AL,CR ;Zeilenende?
- je Parse1
- cmp AL,'/' ;Optionszeichen ?
- je Option1
- cmp AL,'-' ;altern. Optionszeichen ?
- je Option1
- mov CX,AX
- sub CL,'0' ;numerisch ?
- jb ParsNxt ;Nein
- cmp CL,9
- ja ParsNxt ;Nein
- mov AX,10
- mul DX ;bisheriger Wert * 10
- add AX,CX ;neuen Wert hinzuzhlen
- mov DX,AX
- jmp ParsNxt
- Option1:mov AL,ES:[DI]
- inc DI
- mov BH,AL
- cmp BH,'A' ;Expanded Memory ?
- jne Option2 ;Nein, weiter
- mov MemTyp,EXPANDED ;Speicherflag setzen
- jmp ParsNxt
- Option2:cmp BH,'D' ;DOS-Speicher
- je ParsNxt ;keine weitere Optionen
- or ErrFlag,OPT_ERR
- jmp short Parse2
- Parse1: cmp DX,MIN_REQ ;Mindestgráe einstellen
- ja Parse2
- mov DX,MIN_REQ
- Parse2: test MemTyp,EXPANDED
- jz Parse3
- and DX,NOT 15 ;Auf volle 16kB abrunden
- mov Npages,DX
- mov CX,4
- shr Npages,CL
- Parse3: ret
-
- ;-----( BPB-Daten berechnen )-------------------------------
- ; BPB-Daten berechnen und in den Bootrecord schreiben.
- ; Pro 4 KB Diskkapazitt wird ein Root-Verzeichnis-Eintrag
- ; zugelassen (bis max 512). Wir verwenden eine 12-Bit-FAT.
- ; Dadurch ist die maximale Anzahl Clusters 0FF7hex(4087).
- ; Eingabe: DX = Diskgráe in KByte
- ; Ausgabe: AX,BX,CX,DX zerstrt
- ;-----------------------------------------------------------
- Parms: mov DiskSz,DX
- shl DiskSz,1 ;Anzahl Sektoren
- shr DX,1 ;Anzahl Verzeichnisse
- shr DX,1
- cmp DX,512 ;< 512 ?
- jb SetDir ;Ja
- mov DX,512
- SetDir: mov NDir,DX ;Anzahl Verzeichnisse
- mov AX,DiskSz
- mov CX,2 ;default= 2 Sektoren/Cluster
- SetClr: shr AX,1 ;Anzahl Cluster auf Disk
- cmp AX,MAXFAT ;zuviele Clusters ?
- jb ClrOk ;Nein
- shl CX,1 ;Sekt/Cluster verdoppeln
- jmp SetClr
- ClrOk: mov ClstrSz,CL ;Anzahl Clusters pro FAT
- mov BX,AX ;AX = Anzahl Clusters
- add AX,BX ;AX = 2 * Clusters
- add AX,BX ;AX = 3 * Clusters
- ;= doppelte FAT Lnge
- add AX,1023 ;aufrunden
- mov CX,10 ; FAT-Lnge
- shr AX,CL ;FATsec = -------------
- mov FATsec,AX ; Byte / Sektor
- ret
-
- ;-----( Speicher reservieren, RDisk-Adresse berechnen )-----
- ; Eingabe: keine
- ; Ausgabe: ES = Segmentadresse der "Disk"
- ;-----------------------------------------------------------
- SetUp: test MemTyp,EXPANDED ;Expanded Memory?
- jz DMEMsu ;Nein
- EMMsu: mov AH,35h ;EMM vorhanden ?
- mov AL,EMM ;Adresse des Int 67h
- int 21h ;bestimmen
- mov DI,0Ah ;ID-String des EMM
- mov SI,offset EMMname
- mov CX,8
- cld
- repz cmpsb ;String vergleichen
- jz EMMsu1
- or ErrFlag,NoEMM_ERR
- jmp short SUexit
- EMMsu1: mov AH,EMMframe ;Segment des EMM-Speichers lesen
- int EMM
- mov FrameSeg,BX
- or AH,AH
- jz EMMsu2
- or ErrFlag,EMM_ERR
- jmp short SUexit
- EMMsu2: mov AH,EMMfree ;Freien Speicher bestimmen
- int EMM
- or AH,AH
- jz EMMsu3
- or ErrFlag,EMM_ERR
- jmp short SUexit
- EMMsu3: or BX,BX ;Speicher belegt ?
- jnz EMMsu4 ;Nein
- or ErrFlag,SZ_ERR
- EMMsu4: cmp Npages,BX ;Genug Speicher ?
- jbe EMMsu5
- or ErrFlag,SZ_ERR
- jmp short SUexit
- EMMsu5: mov AH,EMMalloc ;Speicher im EMM reservieren
- mov BX,Npages ;BX = Anzahl Seiten
- int EMM
- mov EMMhdl,DX ;Handle sichern
- or AH,AH
- jz SUexit
- or ErrFlag,SZ_ERR
- jmp SUexit
- DMEMsu: mov AX,CS ;Speicher berechnen
- add AX,DVCLEN ;Ende des Treibers ist zugl.
- mov FrameSeg,AX ;Anfang der RAM-Disk
- sub DX,DX ;Division vorbereiten
- mov BX,64 ;Paragraphen/KB
- div BX
- add DX,-1 ;auf volle KB aufrunden
- adc AX,MIN_MEM ;+ minimaler freier Speicher
- mov DX,DiskSz ;= Diskgráe in Sektoren
- shr DX,1 ;/2 = Diskgráe in KB
- add AX,DX ;Erforderlicher Speicher
- push AX ;Wert sichern
- int 12h ;Speichergráe bestimmen
- pop DX
- sub AX,DX ;groá genug ?
- jnc SUexit ;Ja
- or ErrFlag,SZ_ERR ;Nein, Fehler
- SUexit: mov ES,FrameSeg
- ret
-
- ;-----( RAM-Disk "Formatieren" )---------------------------
- Format: test MemTyp,EXPANDED ;Expanded Memory?
- jnz FrmtEXP ;Ja
- mov DX,CS
- add DX,DRIVERend
- mov ES,DX
- mov BX,DiskSz ;Anzahl Sektoren
- xor AX,AX
- Format1:mov CX,SECSZ/2 ;Worte/Sektor
- xor DI,DI
- rep stosw
- add DX,SECSZ/16
- mov ES,DX ;ES ->nchsten Sektor
- dec BX
- jnz Format1
- jmp Format5
- FrmtEXP:mov ES,FrameSeg ;EMM-Fenster Segment
- mov BX,Npages ;Anzahl EMM-Seiten
- Format2:dec BX ;Seite anwhlen und
- mov AH,EMMmapp ;einblenden
- xor AL,AL
- mov DX,EMMhdl
- int EMM
- or AH,AH ;Fehler ?
- jnz FrmtErr ;Ja!
- mov CX,2000h ;Anzahl Worte/EMMseite
- xor DI,DI
- rep stosw
- or BX,BX
- jnz Format2
- Format5:push DS ;Bootrecord aufbauen
- pop ES ;ES = Datensegment
- mov DI,offset BootBPB
- mov SI,offset BPB
- mov CX,BPBlen
- rep movsb
- sub AX,AX ;Bootrecord kopieren
- call MapSec ;ES:DI -> Sektor 0
- mov SI,offset BootRec
- mov CX,BOOTlen
- rep movsb
- mov DX,CS ;FAT und Verzeichnis
- add DX,DRIVERend ; vorbergehend am Ende
- mov ES,DX ; des Programms aufbauen.
- sub DI,DI ;ES:DI-> auf FAT
- mov AL,MEDIA_ID
- stosb ;Media Descriptor Byte
- mov AX,-1 ;...und zwei FFh Byte
- stosw
- mov AX,512
- mul FATsec
- sub AX,3 ; 3 Byte weniger...
- mov CX,AX ; = Zhler
- sub AX,AX ;Rest der FAT lschen
- rep stosb ;DI zeigt jetzt auf Root
- mov SI,offset VolLabel
- mov CX,VolLen ;"Volume Name" ins
- rep movsb ;Verzeichnis kopieren
- mov AX,32
- mul NDir
- sub AX,VolLen
- mov CX,AX ;CX = Anzahl Bytes im Verz.
- xor AX,AX ;Rest des Verzeichnisses
- rep stosb ;lschen
- jmp short FrmtEnd
- FrmtErr:or ErrFlag,EMM_ERR ;Fehler melden!
- FrmtEnd:ret
-
- ;------( Daten im Request-Header sichern )------------------
- FillRH: mov AX,CS ;Gráe des Treibers
- add AX,DVCLEN
- test MemTyp,EXPANDED
- jnz FillRH1
- mov DX,DiskSz ;Disk ist im Hauptspeicher.
- mov CX,5 ;Diskgráe in Sektoren
- shl DX,CL ;* 2^5 Paragr./Sektor
- add AX,DX
- FillRH1:les DI,ReqHdr ;Fehler bei Installation ?
- test ErrFlag,-1
- jnz FillRH2
- mov RH.Unum,1 ;Anzahl der Gerte
- mov RH.EndOfs,0 ;Programmendeadresse
- mov RH.EndSeg,AX
- mov RH.BPBofs, offset BPBptr
- mov RH.BPBseg,CS ;Adresse des BPB-Zeigers.
- sub AX,AX
- ret
-
- FillRH2:mov RH.Unum,0 ;kein Gert, kein Speicher!
- mov RH.EndOfs,0
- mov RH.EndSeg,CS
- mov AX,GEN_ERR
- ret
-
- ;------( Installation melden )------------------------------
- SignOn: @Print Progname
- test ErrFlag,SZ_ERR ;Installationsfehler melden
- jz SignOn1
- @Print ErrMess3
- SignOnE:@Print ErrMess0
- ret
-
- SignOn1:test ErrFlag,NoEMM_ERR
- jz SignOn2
- @Print ErrMess1
- jmp SignOnE
- SignOn2:test ErrFlag,EMM_ERR
- jz SignOn3
- @Print ErrMess2
- jmp SignOnE
- SignOn3:test ErrFlag,OPT_ERR
- jz SignOn4
- @Print ErrMess4
- jmp SignOnE
- SignOn4:mov AH,30h ;DOS-Version ?
- int 21h
- cmp AL,3 ; 3.xx ?
- jb SignOn5
- les DI,ReqHdr
- mov AL,RH.DrvCode ;Diskbezeichnung holen
- add AL,'A'
- mov Drive,AL
- SignOn5:mov CL,4 ;Reservierte Sektoren:
- mov AX,NDir
- shr AX,CL ; Root-Verzeichnis
- add AX,FATsec ; + FAT
- add AX,2
- and AX,0FFFEh ;auf gerade Zahl aufrunden
- mov DX,DiskSz ;Diskgráe - Res. Sektoren
- sub DX,AX ; = Freie Sektoren
- mov AX,SECSZ ;* (Byte/Sektor)
- mul DX ; = Diskgráe in Byte
- mov SI,offset DiskSize+7
- call BinAsci ;in ASCII umwandeln
- mov AX,NDir ;Anzahl Verzeichnisse
- cwd ;oberes Wort lschen
- mov SI,offset DirNum+7
- call BinAsci
- mov AX,DiskSz ;bentigter Speicher
- mov DX,SECSZ
- mul DX
- mov SI,offset MemSize+7
- call BinAsci
- @Print Mess1 ;Meldungen ausgeben
- @Print Mess2
- mov DX,offset DOSmem
- test MemTyp,EXPANDED
- jz SignOn6
- mov DX,offset EXPmem
- SignOn6:mov AH,9
- int 21h
- @Print Mess3
- ret
-
- ;-----( BIN-Zahl in ASCII String umwandeln )----------------
- ; Eingabe: DX:AX = 32-Bit-Zahl
- ; DS:SI = -> Ende des String Puffers
- ; Ausgabe: DS:SI = -> Anfang des String Puffers
- ;-----------------------------------------------------------
- BinAsci:xor BP,BP
- xchg BP,DX ;BP = oberes Wort
- mov CX,10 ;CX = Teiler
- BAloop: xchg AX,BP ;oberes Wort holen
- xor DX,DX ;Ergebnis lschen
- div CX
- xchg AX,BP ;unteres Wort holen
- div CX
- or DL,'0' ;in ASCII-Zahl umwandeln
- mov [SI],DL ;and drop at target
- dec SI ;set up for next character
- or AX,AX ;noch was zu tun?
- jnz BAloop ;Ja, weiter
- ret
-
- ;-----( Transienter Datenbereich )--------------------------
- EMMname db 'EMMXXXX0' ;Bezeichnung des EMM-Handlers
- VolLabel db 'RDISK V:1.0' ;"Volume" Name: 11 Bytes
- db 28h ;Volume Attribut
- dt 0 ;10 reservierte Bytes
- dw 24576 ;12:00 Uhr
- dw 4865 ;1.August.1989
- db 6 dup (0) ;6 reservierte Bytes
- VolLen = $ - VolLabel ;Lnge
- Mess1 db 'RAM-Disk '
- Drive db '$: $'
- Mess2 db 'erfolgreich installiert.',CR,LF
- DiskSize db ' Bytes verfgbar.',CR,LF
- DirNum db ' Verzeichnisse im ¯Root®.',CR,LF
- MemSize db ' Bytes $'
- DOSmem db 'DOS-Speicher $'
- EXPmem db 'Expanded Memory $'
- Mess3 db 'wurden verwendet.',CR,LF,'$'
- ErrMess1 db 'Kein Expanded Memory vorhanden',CR,LF,'$'
- ErrMess2 db 'Fehler im EMM-Treiber',CR,LF,'$'
- ErrMess3 db 'Zu wenig Speicher frei',CR,LF,'$'
- ErrMess4 db 'Unbekannte Option',CR,LF,'$'
- ErrMess0 db 'RAM-Disk NICHT installiert.',CR,LF,BEEP,'$'
-
- ;-----( Programmende )--------------------------------------
- DRIVERend = ($-Main+15)/16 ;Prog.Lnge in Paragraphen
- CODE ends
- END Main